<?php

namespace app\common\util;
/**
 * @method static get(string $url, array $param, array &$header)
 * @method static post(string $url, string|array $param, array &$header)
 * @method static curl_get(string $url, $param, array $header)
 * @method static curl_post(string $url, $param, array $header)
 */
class HttpUtil
{
    public static function __callStatic($name, $arguments)
    {
        try {
            if (strpos($name, 'curl') === 0) {
                return self::curl_request($arguments[0], $arguments[1], $arguments[2], strtoupper(substr($name, strpos($name, '_') + 1)));
            } else {
                return self::request($arguments[0], $arguments[1], $arguments[2], strtoupper($name));
            }
        }catch (\Exception $exception) {
            trace(['code' => $exception->getCode(), 'msg'=>$exception->getMessage(), 'file'=>$exception->getFile(), 'line'=>$exception->getLine()]);
        }
    }

    public static function request($url, $param, &$header, $method)
    {
        trace($url, 'request.url');
        if (!$url) {
            exit();
        }
        $headerStr = self::handleHeader($header, $param);
        $opts = ['http' => [
            'method' => $method,
            'header' => $headerStr,
            'content' => $param
        ], "ssl" => [
            "verify_peer" => false,
            "verify_peer_name" => false,
        ]];
        $context = stream_context_create($opts);
        $res = file_get_contents($url, false, $context);
        trace($res, 'request.result');
        $header = $http_response_header;
        return $res;
    }

    protected static function handleHeader($header, &$params): array
    {
        $isSetContentType = false;
        $contentType = 'application/json';
        if ($header) {
            foreach ($header as $key => $value) {
                if (strpos(strtolower($key), 'content-type') !== false || strpos(strtolower($value), 'content-type') !== false) {
                    $isSetContentType = true;
                    $contentType = $value;
                }
                $headerStr[] = (is_numeric($key) ? $value : ($key . ': ' . $value));
            }
        }
        if (!$isSetContentType) {
            $headerStr[] = 'Content-type: application/json';
        }
        if (!is_string($params)) {
            if (is_array($params) && $isSetContentType && strpos($contentType, 'json')) {
                $params = json_encode($params);
            }else{
                $params = http_build_query($params);
            }
        }
        $headerStr[] = 'Content-Length: ' . strlen($params);
        trace($headerStr, 'request.header');
        trace($params, 'request.params');
        return $headerStr;
    }

    protected static function curl_request($url, $body, $header, $method)
    {
        $header = self::handleHeader($header, $body);
        trace($url, 'request.url');
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_HEADER, 0);
        curl_setopt($curl, CURLOPT_TIMEOUT, 1);
        curl_setopt($curl, CURLOPT_TIMEOUT_MS, 3000);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        if (strtolower($method) == 'post') {
            curl_setopt($curl, CURLOPT_POST, 1);
        }
        trace($body, 'request.body');
        curl_setopt($curl, CURLOPT_POSTFIELDS, $body);
        $data = curl_exec($curl);
        trace($data, 'request.response');
        curl_close($curl);
        return $data;
    }
}